#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <assert.h>
using namespace std;
//简单的my_string，具体解释见my_string笔记
namespace lcl
{
	class string
	{
	public:

		/*string()
			:_str(nullptr)
		{}
		string(char* str)
			:_str(str)
		{}*/

		/*string()
			:_str(nullptr)
		{}
		string(const char* str)
			:_str(new char[strlen(str)+1])
		{
			strcpy(_str, str);
		}*/

		/*string()
			:_str(new char[1])
		{
			str[0] = '\0'
		}
		string(const char* str)
			:_str(new char[strlen(str)+1])
		{
			strcpy(_str, str);
		}*/

		string(const char* str = "")
			:_str(new char[strlen(str) + 1])  //+1是为了保存'\0',以满足C语言的用法
		{  
			strcpy(_str, str);
		}

		//需要深拷贝，浅拷贝有问题 string s2(s1);
		/*string(const string& s)
			:_str(new char[strlen(s._str) + 1])
		{
			strcpy(_str, s._str);
		}*/

		string(const string& s)
			:_str(nullptr) //这里需要初始化为空，不然_str为随机值，换过去析构时会崩溃
		{
			string tmp(s._str); //s._str是指针，所以该处调用的是上面的构造函数
			swap(_str,tmp._str);
		}

		//赋值  s1 = s2;
		/*string& operator=(const string& s)
		{
			char* _str = new char[strlen(s._str) + 1];
			strcpy(_str, s._str);
			return *this;
		}*/

		/*string& operator=(const string& s)
		{
			if (this != &s)
			{
				char* pStr = new char[strlen(s._str) + 1];
				strcpy(pStr, s._str);
				delete[] _str;
				_str = pStr;
			}
			return *this;
		}*/

		//string& operator=(const string& s)
		//{
		//	if (this != &s)
		//	{
		//		//string tmp(s); //这里调用的是上面的拷贝构造
		//		string tmp(s._str); //这里是构造
		//		swap(_str, tmp._str);
		//	}
		//	return *this;
		//}

		string& operator=(string s)
		{
			swap(_str, s._str);
			return *this;
		}


		size_t size()
		{
			return strlen(_str);
		}
		char& operator[](size_t i)
		{
			return _str[i];
		}

		~string()
		{
			if (_str)
			{
				delete[] _str;
				_str = nullptr;
			}
		}

	private:
		char* _str;
	};

	void test()
	{
		string s1("hello");
		string s2("world");
		string s3(s2);
		string s4;
		s4 = s1;

		for (size_t i = 0; i < s4.size(); ++i)
		{
			cout << s4[i];
		}
		cout << endl;

		for (size_t i = 0; i < s3.size(); ++i)
		{
			cout << s3[i];
		}


	}
}

//具体解释看笔记my_string
//my_string
//
//namespace lcl
//{
//	class string
//	{
//	public:
//		typedef char* iterator;
//
//		iterator begin()
//		{
//			return _str;
//		}
//		iterator end()
//		{
//			return _str + _size;
//		}
//
//		string(const char* str = "")
//		{
//			_size = strlen(str);
//			_capacity = _size;				//_capacity是能存多少个有效字符
//			_str = new char[_capacity + 1]; //为什么是+1，要存'\0'，'\0'不是有效字符，
//			strcpy(_str, str);
//		}
//      
//      string(const string& s)
//      :_str(nullptr)
//      ,_size(0)
//      ,_capacity(0)
//      {
//          string tmp(s);
//          swap(tmp);
//      }
//
//      void swap(string& s)
//      {
//          ::swap(_str,s._str);
//          ::swap(_size,s._size);
//          ::swap(_capacity,s._capacity);
//      }
//		
//		string& operator=(string s)
//      {
//          swap(s);
//          return *this;
//      }
//
//		~string()
//		{
//			if (_str)
//			{
//				delete[] _str;
//				_str = nullptr;
//				_size = _capacity = 0;
//			}
//		}
//
//		size_t size()const
//		{
//			return _size;
//		}
//
//		size_t capacity()const
//		{
//			return _capacity;
//		}
//
//		char& operator[](size_t i)
//		{
//			assert(i < _size);
//			return _str[i];
//		}
//
//		const char& operator[](size_t i)const
//		{
//			assert(i < _size);
//			return _str[i];
//		}
//
//		const char* c_str()const
//		{
//			return _str;
//		}
//	private:
//		char* _str;
//		int _size;
//		int _capacity;
//	};
//
//	void test2()
//	{
//		string s1("hello");
//		string s2;
//
//		//范围for由迭代器支持的，这段代码最终会被编译器替换成迭代器。
//		//iterator begin() end()
//		for (auto ch : s1)
//		{
//			cout << ch << " ";
//		}
//
//	}
//}